﻿using System;
using System.Collections;
using System.IO;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace Kiiro.Logging
{
    public class LoggingManager
    {
        #region Field Variables

        private const string _logFile = "Kiiro";
        private const string LogExtension = ".log";

        #endregion

        #region Properties

        internal string LineToLog
        {
            get;
            set;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// This will actually log the content to the actual file.
        /// </summary>
        /// <remarks>Should be called by the <c>SPSecurity.RunWithElevatedPrivileges</c></remarks>
        internal void Write()
        {
            string actualFileName = GetCurrentLogFile(_logFile);
            using (StreamWriter file = File.AppendText(actualFileName))
            {
                lock (file)
                {
                    file.WriteLine(LineToLog);
                    file.Flush();
                    file.Close();
                }
            }
        }

        /// <summary>
        /// Log a message to <c>logfile</c>
        /// </summary>
        /// <param name="category">a category to log</param>
        /// <param name="message">the message to log</param>
        public static void LogMessage(string category, string message)
        {
            LoggingManager l = new LoggingManager();
            l.LineToLog = string.Format("{0}\t{1}\t{2}",
                                        DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"),
                                        category.PadLeft(25),
                                        message);
            // this way we can always write to the logfiles
            SPSecurity.CodeToRunElevated log = l.Write;
            SPSecurity.RunWithElevatedPrivileges(log);
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Parse/handle/cleanup the logfiles for the baselogname <c>logfile</c>
        /// </summary>
        /// <param name="logfile">the basename for the logfiles</param>
        /// <returns>the actual filename to log to</returns>
        private static string GetCurrentLogFile(string logfile)
        {
            string timestamp =
                DateTime.Now.AddMinutes(-SPDiagnosticsService.Local.LogCutInterval).
                    ToString("yyyyMMdd-HHmm");

            string lastAllowedLogFileName = Path.Combine(
                SPDiagnosticsService.Local.LogLocation,
                logfile + "-" + timestamp + LogExtension);
            // get existing logfiles
            string[] files =
                Directory.GetFiles(SPDiagnosticsService.Local.LogLocation,
                                   logfile + "*.log", SearchOption.TopDirectoryOnly);

            ArrayList list = new ArrayList();
            list.AddRange(files);

            // clean up old log files
            if (list.Count > SPDiagnosticsService.Local.LogsToKeep)
            {
                int count = list.Count;
                while (count > SPDiagnosticsService.Local.LogsToKeep)
                {
                    File.Delete(list[0] as string);
                    count--;
                }
            }
            // lookup current logfile
            string currentLogFile = "";
            if (list.Count > 0)
            {
                string lastfile = list[list.Count - 1] as string;
                if (string.Compare(lastfile, lastAllowedLogFileName) > 0)
                {
                    currentLogFile = lastfile;
                }
            }
            // create a new logfile
            if (currentLogFile == "")
            {
                string timestampn = DateTime.Now.ToString("yyyyMMdd-HHmm");
                currentLogFile = Path.Combine(
                    SPDiagnosticsService.Local.LogLocation,
                    logfile + "-" + timestampn + LogExtension);
            }
            return currentLogFile;
        }

        #endregion
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Logging/LoggingManager.cs $
 * 
 * 3     17/08/09 10:45a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/